﻿Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Class GraphicsHelper

    Public Function GetRoundCornerPathForRectangle(rect As Rectangle) As System.Drawing.Drawing2D.GraphicsPath
        Dim path As New System.Drawing.Drawing2D.GraphicsPath()
        path.Reset()

        'left side
        path.AddLine(rect.Left, rect.Bottom - 2, _
                     rect.Left, rect.Top + 2)
        'left-top corner
        path.AddLine(rect.Left, rect.Top + 2, _
                     rect.Left + 2, rect.Top)
        'top side
        path.AddLine(rect.Left + 2, rect.Top, _
                     rect.Right - 2, rect.Top)
        'top right corner
        path.AddLine(rect.Right - 2, rect.Top, _
                     rect.Right, rect.Top + 2)
        'right side
        path.AddLine(rect.Right, rect.Top + 2, _
                     rect.Right, rect.Bottom - 2)
        'bottom-right corner
        path.AddLine(rect.Right, rect.Bottom - 2, _
                     rect.Right - 2, rect.Bottom)
        'bottom side
        path.AddLine(rect.Right - 2, rect.Bottom, _
                     rect.Left + 2, rect.Bottom)
        'bottom-left corner
        path.AddLine(rect.Left + 2, rect.Bottom, _
                     rect.Left, rect.Bottom - 2)

        Return path
    End Function

    Public Function GetTextRectangle(text As String, _
                                  font As Font, _
                                  cRect As Rectangle, _
                                  g As Graphics, _
                                  align As ContentAlignment) As Rectangle

        TextRenderer.MeasureText(text, font)


        'measure text rectangle
        Dim textSize As Size = g.MeasureString(text, font, cRect.Width).ToSize

        'Get the text rectangle
        Dim tRect As Rectangle = Nothing
        Select Case align
            Case Else
                tRect = New Rectangle(cRect.Left, cRect.Bottom - textSize.Height, cRect.Width, textSize.Height)
        End Select

        Return tRect
    End Function

    Public Function GetTextRectangle(text As String, font As Font) As Rectangle
        Dim tSize As Size = TextRenderer.MeasureText(text, font)
        Return New Rectangle(0, 0, tSize.Width, tSize.Height)
    End Function

    Public Function GetTextSize(text As String, font As Font) As Size
        Return TextRenderer.MeasureText(text, font)
    End Function

    Public Function GetImageAlpha(alpha As Integer, img As Image) As Image
        Dim sample As Bitmap = img.Clone

        For x As Integer = 0 To sample.Width - 1
            For y As Integer = 0 To sample.Height - 1
                Dim clr As Color = sample.GetPixel(x, y)
                clr = Color.FromArgb(alpha, clr)
                sample.SetPixel(x, y, clr)
            Next
        Next

        Return sample
    End Function

    Public Function GetImageRectangleProportionalAligned(img As Image, _
                                                         bounds As Rectangle, _
                                                         imageLocation As ImagePositioningsEnum) As Rectangle

        'Get the proportioned new image size
        'Dim proportionalImageSize As Size = Me.GetImageProportionalSize(img, bounds)
        Dim proportionalImageSize As Size = Me.GetImageProportionalSize(img, bounds)

        'Align image
        Dim nX As Integer = 0
        Dim nY As Integer = 0
        Select Case imageLocation
            Case Is = ImagePositioningsEnum.Left
                'center vertically on left side
                nX = bounds.X
                nY = bounds.Y + ((bounds.Height / 2) - (proportionalImageSize.Height / 2))
            Case Is = ImagePositioningsEnum.Right
                'center vertically on right side
                nX = bounds.Right - img.Width
                nY = bounds.Y + ((bounds.Height / 2) - (proportionalImageSize.Height / 2))
            Case Is = ImagePositioningsEnum.Top
                'center horizontally on top
                nX = bounds.X + ((bounds.Width / 2) - (proportionalImageSize.Width / 2))
                nY = bounds.Y
            Case Is = ImagePositioningsEnum.Bottom
                'center horizontally on bottom
                nX = bounds.X + ((bounds.Width / 2) - (proportionalImageSize.Width / 2))
                nY = bounds.Bottom - img.Height
        End Select

        Dim imageRectangle As New Rectangle(nX, nY, proportionalImageSize.Width, proportionalImageSize.Height)

        Return imageRectangle
    End Function

    Public Function GetImageRectangleProportionalAligned(img As Image, _
                                                         imageMaxWidth As Integer, _
                                                         imageMaxHeight As Integer, _
                                                         bounds As Rectangle, _
                                                         imageLocation As ImagePositioningsEnum) As Rectangle

        'Get the proportioned new image size
        Dim proportionalImageSize As Size = Me.GetImageProportionalSize(img, imageMaxWidth, imageMaxHeight)

        'Align image
        Dim nX As Integer = 0
        Dim nY As Integer = 0
        Select Case imageLocation
            Case Is = ImagePositioningsEnum.Left
                'center vertically on left side
                nX = bounds.X
                nY = bounds.Y + ((bounds.Height / 2) - (proportionalImageSize.Height / 2))
            Case Is = ImagePositioningsEnum.Right
                'center vertically on right side
                nX = bounds.Right - img.Width
                nY = bounds.Y + ((bounds.Height / 2) - (proportionalImageSize.Height / 2))
            Case Is = ImagePositioningsEnum.Top
                'center horizontally on top
                nX = bounds.X + ((bounds.Width / 2) - (proportionalImageSize.Width / 2))
                nY = bounds.Y
            Case Is = ImagePositioningsEnum.Bottom
                'center horizontally on bottom
                nX = bounds.X + ((bounds.Width / 2) - (proportionalImageSize.Width / 2))
                nY = bounds.Bottom - img.Height
        End Select

        Dim imageRectangle As New Rectangle(nX, nY, img.Width, img.Height)

        Return imageRectangle
    End Function

    Public Function GetImageProportionalSize(img As Image, maxWidth As Integer, maxHeight As Integer) As Size
        Dim aWidth As Integer = maxWidth
        Dim aHeight As Integer = maxHeight
        Dim iWidth As Integer = img.Width
        Dim iHeight As Integer = img.Height
        Dim nWidth As Integer = 0
        Dim nHeight As Integer = 0
        Dim prop As Double = 1

        'Calculate proportions
        If iWidth = iHeight Then
            If aWidth > aHeight Then
                nWidth = aHeight
                nHeight = aHeight
            Else
                nWidth = aWidth
                nHeight = aWidth
            End If
        ElseIf iWidth > iHeight Then
            nWidth = aWidth
            nHeight = (iHeight * aWidth) / iWidth
        Else
            nHeight = nHeight
            nWidth = (iWidth * aHeight) / iHeight
        End If

        Dim newImageSize As New Size(nWidth, nHeight)

        Return newImageSize

    End Function

    Public Function GetImageProportionalSize(img As Image, layout As Rectangle) As Size
        Dim aWidth As Integer = layout.Width
        Dim aHeight As Integer = layout.Height
        Dim iWidth As Integer = img.Width
        Dim iHeight As Integer = img.Height
        Dim nWidth As Integer = 0
        Dim nHeight As Integer = 0
        Dim prop As Double = 1

        'Calculate proportions
        If iWidth = iHeight Then
            If aWidth > aHeight Then
                nWidth = aHeight
                nHeight = aHeight
            Else
                nWidth = aWidth
                nHeight = aWidth
            End If
        ElseIf iWidth > iHeight Then
            nWidth = aWidth
            nHeight = (iHeight * aWidth) / iWidth
        Else
            nHeight = aHeight
            nWidth = (iWidth * aHeight) / iHeight
        End If

        Dim newImageSize As New Size(nWidth, nHeight)

        Return newImageSize

    End Function

    Public Function GetImageRectangleProportionalCentered(img As Image, iRect As Rectangle) As Rectangle

        Dim newImageSize As Size = Me.GetImageProportionalSize(img, iRect)

        'Center image
        Dim nX As Integer = 0
        Dim nY As Integer = 0
        nX = iRect.X + ((iRect.Width / 2) - (newImageSize.Width / 2))
        nY = iRect.Y + ((iRect.Height / 2) - (newImageSize.Height / 2))
        Dim iRect2 As New Rectangle(nX, nY, newImageSize.Width, newImageSize.Height)
        Return iRect2

    End Function

    Public Function GetImageRectangleCentered(img As Image, iRect As Rectangle) As Rectangle

        'Center image
        Dim nX As Integer = 0
        Dim nY As Integer = 0
        nX = iRect.X + ((iRect.Width / 2) - (img.Size.Width / 2))
        nY = iRect.Y + ((iRect.Height / 2) - (img.Size.Height / 2))
        Dim iRect2 As New Rectangle(nX, nY, img.Size.Width, img.Size.Height)
        Return iRect2

    End Function

    Public Sub DrawTextNormal(g As Graphics, _
                           text As String, _
                           Font As Font, _
                           foreColor As Color, _
                           tRect As Rectangle, _
                           Optional sf As StringFormat = Nothing)
        If sf IsNot Nothing Then
            g.DrawString(text, Font, New SolidBrush(foreColor), tRect, sf)
        Else
            g.DrawString(text, Font, New SolidBrush(foreColor), tRect)
        End If

    End Sub

    Public Sub DrawTextWithGlow(g As Graphics, _
                                cRect As Rectangle, _
                                Text As String, _
                                Font As Font, _
                                GlowColor As Color, _
                                ForeColor As Color, _
                                Optional sf As StringFormat = Nothing)

        Using path As GraphicsPath = GetTextPath(Text, Font, cRect, sf)

            'Draw the glow
            Using pen As Pen = New Pen(Color.FromArgb(65, GlowColor), 4)
                pen.LineJoin = LineJoin.Round
                g.DrawPath(pen, path)
            End Using
            Using pen As Pen = New Pen(Color.FromArgb(160, GlowColor), 2)
                pen.LineJoin = LineJoin.Round
                g.DrawPath(pen, path)
            End Using

            'Draw the text
            path.FillMode = FillMode.Winding
            g.FillPath(New SolidBrush(ForeColor), path)

        End Using

    End Sub

    Public Function GetTextPath(Text As String, _
                                  Font As Font, _
                                  cRect As Rectangle, _
                                  sf As StringFormat) As GraphicsPath
        Dim path As New GraphicsPath
        'create a GraphicsPath of the text
        'Because the GraphicsPath does not match exactly with
        'Drawing a String normally, multiply the font Size by
        '1.26 to get a pretty close representation of the size.
        path.AddString(Text, Font.FontFamily, Font.Style, CInt(Font.Size * 1.26), cRect, sf)

        Return path
    End Function

    Public Function GetTextRectangleOpositeToImageRectangle(bounds As Rectangle, _
                                                            imageRectangle As Rectangle, _
                                                            imagePosition As ImagePositioningsEnum) As Rectangle
        Dim tRect As Rectangle = Nothing
        Select Case imagePosition
            Case Is = ImagePositioningsEnum.Left
                'text has to be right
                tRect = New Rectangle(bounds.Left + imageRectangle.Width + 1, _
                                      bounds.Y, _
                                      bounds.Width - imageRectangle.Width - 1, _
                                      bounds.Height)
            Case Is = ImagePositioningsEnum.Right
                'text has to be left
                tRect = New Rectangle(bounds.X, _
                                      bounds.Y, _
                                      bounds.Width - imageRectangle.Width - 1, _
                                      bounds.Height)
            Case Is = ImagePositioningsEnum.Top
                'text has to be bottom
                tRect = New Rectangle(bounds.X, _
                                      bounds.Y + imageRectangle.Height + 1, _
                                      bounds.Width, _
                                      bounds.Height - imageRectangle.Height - 1)
            Case Is = ImagePositioningsEnum.Bottom
                'text has to be top
                tRect = New Rectangle(bounds.X, _
                                      bounds.Y, _
                                      bounds.Width, _
                                      bounds.Height - imageRectangle.Height - 1)
        End Select

        Return tRect
    End Function

    Public Function GetTextFormatObjectFromContentAlignment(alignment As ContentAlignment) As StringFormat
        Dim sf As New StringFormat
        'setup horizontal alignment
        Select Case alignment
            Case Is = ContentAlignment.TopCenter, ContentAlignment.MiddleCenter, ContentAlignment.BottomCenter
                sf.Alignment = StringAlignment.Center
            Case Is = ContentAlignment.TopLeft, ContentAlignment.MiddleLeft, ContentAlignment.BottomLeft
                sf.Alignment = StringAlignment.Near
            Case Is = ContentAlignment.TopRight, ContentAlignment.MiddleRight, ContentAlignment.BottomRight
                sf.Alignment = StringAlignment.Far
        End Select
        'setup vertical alignment
        Select Case alignment
            Case Is = ContentAlignment.MiddleCenter, ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight
                sf.LineAlignment = StringAlignment.Center
            Case Is = ContentAlignment.TopCenter, ContentAlignment.TopLeft, ContentAlignment.TopRight
                sf.LineAlignment = StringAlignment.Near
            Case Is = ContentAlignment.BottomCenter, ContentAlignment.BottomLeft, ContentAlignment.BottomRight
                sf.LineAlignment = StringAlignment.Far
        End Select
        Return sf
    End Function

    Public Function GetTextSize(controlHandle As System.IntPtr, _
                                  text As String, _
                                  font As Font, _
                                  maxWidth As Integer, _
                                  Optional sf As StringFormat = Nothing) As Size
        Dim layoutsize As SizeF = New SizeF(maxWidth, 5000.0)
        Dim g As Graphics = Graphics.FromHwnd(controlHandle)
        Dim StringSize As SizeF = g.MeasureString(text, font, layoutsize, sf)
        Dim rHeight As Integer = StringSize.Height
        Return New Size(maxWidth, rHeight)
    End Function

    Public Function GetGrayColorColor(ByVal ColorIn As Color, Enabled As Boolean) As Color
        If Enabled Then
            Return ColorIn
        Else
            Dim gray As Integer = CInt(ColorIn.R * 0.3 + ColorIn.G * 0.59 + ColorIn.B * 0.11)
            Return Color.FromArgb(ColorIn.A, gray, gray, gray)
        End If
    End Function

    Public Function GetGrayColorBlends(ByVal ColorIn As Color(), Enabled As Boolean) As Color()

        If Enabled Then
            Return ColorIn
        Else
            Dim tcolor As New List(Of Color)
            For Each c As Color In ColorIn
                Dim gray As Integer = CInt(c.R * 0.3 + c.G * 0.59 + c.B * 0.11)
                tcolor.Add(Color.FromArgb(c.A, gray, gray, gray))
            Next
            Return tcolor.ToArray
        End If
    End Function

    Public Function ScreenResolution() As Size
        Dim intX As Integer = My.Computer.Screen.Bounds.Width
        Dim intY As Integer = My.Computer.Screen.Bounds.Height
        Return New Size(intX, intY)
    End Function

End Class

Public Enum ImagePositioningsEnum As Integer
    Left = 0
    Right = 1
    Top = 2
    Bottom = 3
End Enum

Public Class RGBHSL

    ''' <summary>
    ''' Courtesy of Bob Powell you can find the original article at bobpowell.net
    ''' </summary>
    ''' <remarks></remarks>
    ''' <link>http://www.bobpowell.net/rgbhsb.htm</link>

    Public Class HSL

        Private _h As Double
        Public Property H() As Double
            Get
                Return _h
            End Get
            Set(value As Double)
                _h = value
                _h = IIf(_h > 1, 1, IIf(_h < 0, 0, _h))
            End Set
        End Property

        Private _s As Double
        Public Property S() As Double
            Get
                Return _s
            End Get
            Set(value As Double)
                _s = value
                _s = IIf(_s > 1, 1, IIf(_s < 0, 0, _s))
            End Set
        End Property

        Private _l As Double
        Public Property L() As Double
            Get
                Return _l
            End Get
            Set(value As Double)
                _l = value
                _l = IIf(_l > 1, 1, IIf(_l < 0, 0, _l))
            End Set
        End Property

        Public Sub New()
            _h = 0
            _s = 0
            _l = 0
        End Sub 'New

    End Class 'HSL

    Public Sub New()
    End Sub 'New

    ''' <summary>
    ''' Sets the absolute brightness of a colour
    ''' </summary>
    ''' <param name="c">Original colour</param>
    ''' <param name="brightness">The luminance level to impose</param>
    ''' <returns>an adjusted colour</returns>
    Public Shared Function SetBrightness(c As Color, brightness As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        MsgBox(hsl.L)
        hsl.L = brightness
        Return HSL_to_RGB(hsl)
    End Function 'SetBrightness

    ''' <summary>
    ''' Modifies an existing brightness level
    ''' </summary>
    ''' <remarks>
    ''' To reduce brightness use a number smaller than 1. To increase brightness use a number larger tnan 1
    ''' </remarks>
    ''' <param name="c">The original colour</param>
    ''' <param name="brightness">The luminance delta</param>
    ''' <returns>An adjusted colour</returns>
    Public Shared Function ModifyBrightness(c As Color, brightness As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.L *= brightness
        Return HSL_to_RGB(hsl)
    End Function 'ModifyBrightness

    ''' <summary>
    ''' Sets the absolute saturation level
    ''' </summary>
    ''' <remarks>Accepted values 0-1</remarks>
    ''' <param name="c">An original colour</param>
    ''' <param name="Saturation">The saturation value to impose</param>
    ''' <returns>An adjusted colour</returns>
    Public Shared Function SetSaturation(c As Color, Saturation As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.S = Saturation
        Return HSL_to_RGB(hsl)
    End Function 'SetSaturation

    ''' <summary>
    ''' Modifies an existing Saturation level
    ''' </summary>
    ''' <remarks>
    ''' To reduce Saturation use a number smaller than 1. To increase Saturation use a number larger tnan 1
    ''' </remarks>
    ''' <param name="c">The original colour</param>
    ''' <param name="Saturation">The saturation delta</param>
    ''' <returns>An adjusted colour</returns>
    Public Shared Function ModifySaturation(c As Color, Saturation As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.S *= Saturation
        Return HSL_to_RGB(hsl)
    End Function 'ModifySaturation

    ''' <summary>
    ''' Sets the absolute Hue level
    ''' </summary>
    ''' <remarks>Accepted values 0-1</remarks>
    ''' <param name="c">An original colour</param>
    ''' <param name="Hue">The Hue value to impose</param>
    ''' <returns>An adjusted colour</returns>
    Public Shared Function SetHue(c As Color, Hue As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.H = Hue
        Return HSL_to_RGB(hsl)
    End Function 'SetHue

    ''' <summary>
    ''' Modifies an existing Hue level
    ''' </summary>
    ''' <remarks>
    ''' To reduce Hue use a number smaller than 1. To increase Hue use a number larger tnan 1
    ''' </remarks>
    ''' <param name="c">The original colour</param>
    ''' <param name="Hue">The Hue delta</param>
    ''' <returns>An adjusted colour</returns>
    Public Shared Function ModifyHue(c As Color, Hue As Double) As Color
        Dim hsl As HSL = RGB_to_HSL(c)
        hsl.H *= Hue
        Return HSL_to_RGB(hsl)
    End Function 'ModifyHue

    ''' <summary>
    ''' Converts a colour from HSL to RGB
    ''' </summary>
    ''' <remarks>Adapted from the algoritm in Foley and Van-Dam</remarks>
    ''' <param name="hsl">The HSL value</param>
    ''' <returns>A Color structure containing the equivalent RGB values</returns>
    Public Shared Function HSL_to_RGB(hsl As HSL) As Color
        Dim r As Double = 0
        Dim g As Double = 0
        Dim b As Double = 0
        Dim temp1, temp2 As Double

        If hsl.L = 0 Then
            r = 0
            g = 0
            b = 0
        Else
            If hsl.S = 0 Then
                r = hsl.L
                g = hsl.L
                b = hsl.L
            Else
                temp2 = IIf(hsl.L <= 0.5, hsl.L * (1.0 + hsl.S), hsl.L + hsl.S - hsl.L * hsl.S)
                temp1 = 2.0 * hsl.L - temp2

                Dim t3() As Double = {hsl.H + 1.0 / 3.0, hsl.H, hsl.H - 1.0 / 3.0}
                Dim clr() As Double = {0, 0, 0}
                Dim i As Integer
                For i = 0 To 2
                    If t3(i) < 0 Then
                        t3(i) += 1.0
                    End If
                    If t3(i) > 1 Then
                        t3(i) -= 1.0
                    End If
                    If 6.0 * t3(i) < 1.0 Then
                        clr(i) = temp1 + (temp2 - temp1) * t3(i) * 6.0
                    ElseIf 2.0 * t3(i) < 1.0 Then
                        clr(i) = temp2
                    ElseIf 3.0 * t3(i) < 2.0 Then
                        clr(i) = temp1 + (temp2 - temp1) * (2.0 / 3.0 - t3(i)) * 6.0
                    Else
                        clr(i) = temp1
                    End If
                Next i
                r = clr(0)
                g = clr(1)
                b = clr(2)
            End If
        End If

        Return Color.FromArgb(CInt(255 * r), CInt(255 * g), CInt(255 * b))
    End Function 'HSL_to_RGB

    ''' <summary>
    ''' Converts RGB to HSL
    ''' </summary>
    ''' <remarks>Takes advantage of whats already built in to .NET by using the Color.GetHue, Color.GetSaturation and Color.GetBrightness methods</remarks>
    ''' <param name="c">A Color to convert</param>
    ''' <returns>An HSL value</returns>
    Public Shared Function RGB_to_HSL(c As Color) As HSL
        Dim hsl As New HSL()
        hsl.H = c.GetHue() / 360.0 ' we store hue as 0-1 as opposed to 0-360
        hsl.L = c.GetBrightness()
        hsl.S = c.GetSaturation()
        Return hsl
    End Function 'RGB_to_HSL

End Class 'RGBHSL

''' <summary>
''' this is a collection of shared methods to help drawing the controls
''' </summary>
''' <remarks></remarks>
Public Class Helpers
    ''' <summary>
    ''' this function returns the first non-transparent color of a control's parent(s)
    ''' loops through all parents to find the first non transparent color
    ''' </summary>
    ''' <param name="ctrl"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function GetNonTransparentBackColor(ByVal ctrl As Control) As Color
        Dim bc As Color, p As Control
        Try
            p = ctrl.Parent
            bc = p.BackColor
            While bc.Equals(Color.Transparent) And Not p.Parent Is Nothing
                p = p.Parent
                bc = p.BackColor
            End While

            If bc.Equals(Color.Transparent) Then bc = SystemColors.Control

            Return bc
        Catch ex As Exception
            Return SystemColors.Control
        End Try
    End Function

    ''' <summary>
    ''' this function returns a checked rectangle (width and height always > 1)
    ''' </summary>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <param name="width"></param>
    ''' <param name="height"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function CheckedRectangleF(ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single) As RectangleF
        Return New RectangleF(x, y, CSng(IIf(width <= 0, 1, width)), CSng(IIf(height <= 0, 1, height)))
    End Function

    ''' <summary>
    ''' this function returns a checked rectangle (width and height always > 1)
    ''' </summary>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <param name="width"></param>
    ''' <param name="height"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function CheckedRectangle(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer) As Rectangle
        Return New Rectangle(x, y, CInt(IIf(width <= 0, 1, width)), CInt(IIf(height <= 0, 1, height)))
    End Function

    ''' <summary>
    ''' converts a rectangel structure to a RectangleF structure
    ''' </summary>
    ''' <param name="rect"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ConvertToRectangleF(ByVal rect As Rectangle) As RectangleF
        Return New RectangleF(rect.X, rect.Y, rect.Width, rect.Height)
    End Function

    ''' <summary>
    ''' converts a RectangleF structure to a rectangle structure
    ''' </summary>
    ''' <param name="rect"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function ConvertToRectangle(ByVal rect As RectangleF) As Rectangle
        Return New Rectangle(CInt(rect.X), CInt(rect.Y), CInt(rect.Width), CInt(rect.Height))
    End Function
End Class


<Flags()> _
Public Enum Corner
    None = 0
    TopLeft = 1
    TopRight = 2
    BottomLeft = 4
    BottomRight = 8
    All = TopLeft Or TopRight Or BottomLeft Or BottomRight
End Enum

''' <summary>
''' predefined paths for drawing routines
''' </summary>
''' <remarks></remarks>
Public Class Paths

#Region "RoundedRect"
    Public Shared Function RoundedRect(ByVal rect As RectangleF, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Dim p As New Drawing2D.GraphicsPath
        Dim x As Single = rect.X, y As Single = rect.Y, w As Single = rect.Width, h As Single = rect.Height, m As Integer = margin, r As Integer = cornerradius

        p.StartFigure()
        'top left arc
        If CBool(roundedcorners And Corner.TopLeft) Then
            p.AddArc(Helpers.CheckedRectangleF(x + m, y + m, 2 * r, 2 * r), 180, 90)
        Else
            p.AddLine(New PointF(x + m, y + m + r), New PointF(x + m, y + m))
            p.AddLine(New PointF(x + m, y + m), New PointF(x + m + r, y + m))
        End If

        'top line
        p.AddLine(New PointF(x + m + r, y + m), New PointF(x + w - m - r, y + m))

        'top right arc
        If CBool(roundedcorners And Corner.TopRight) Then
            p.AddArc(Helpers.CheckedRectangleF(x + w - m - 2 * r, y + m, 2 * r, 2 * r), 270, 90)
        Else
            p.AddLine(New PointF(x + w - m - r, y + m), New PointF(x + w - m, y + m))
            p.AddLine(New PointF(x + w - m, y + m), New PointF(x + w - m, y + m + r))
        End If

        'right line
        p.AddLine(New PointF(x + w - m, y + m + r), New PointF(x + w - m, y + h - m - r))

        'bottom right arc
        If CBool(roundedcorners And Corner.BottomRight) Then
            p.AddArc(Helpers.CheckedRectangleF(x + w - m - 2 * r, y + h - m - 2 * r, 2 * r, 2 * r), 0, 90)
        Else
            p.AddLine(New PointF(x + w - m, y + h - m - r), New PointF(x + w - m, y + h - m))
            p.AddLine(New PointF(x + w - m, y + h - m), New PointF(x + w - m - r, y + h - m))
        End If

        'bottom line
        p.AddLine(New PointF(x + w - m - r, y + h - m), New PointF(x + m + r, y + h - m))

        'bottom left arc
        If CBool(roundedcorners And Corner.BottomLeft) Then
            p.AddArc(Helpers.CheckedRectangleF(x + m, y + h - m - 2 * r, 2 * r, 2 * r), 90, 90)
        Else
            p.AddLine(New PointF(x + m + r, y + h - m), New PointF(x + m, y + h - m))
            p.AddLine(New PointF(x + m, y + h - m), New PointF(x + m, y + h - m - r))
        End If

        'left line
        p.AddLine(New PointF(x + m, y + h - m - r), New PointF(x + m, y + m + r))

        'close figure...
        p.CloseFigure()

        Return p
    End Function

    Public Shared Function RoundedRect(ByVal location As Point, ByVal size As Size, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Return RoundedRect(Helpers.CheckedRectangleF(location.X, location.Y, size.Width, size.Height), cornerradius, margin, roundedcorners)
    End Function

    Public Shared Function RoundedRect(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Return RoundedRect(Helpers.CheckedRectangleF(x, y, width, height), cornerradius, margin, roundedcorners)
    End Function

    Public Shared Function RoundedRect(ByVal rect As Rectangle, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Return RoundedRect(Helpers.CheckedRectangleF(rect.Left, rect.Top, rect.Width, rect.Height), cornerradius, margin, roundedcorners)
    End Function

    Public Shared Function RoundedRect(ByVal location As PointF, ByVal size As SizeF, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Return RoundedRect(Helpers.CheckedRectangleF(location.X, location.Y, size.Width, size.Height), cornerradius, margin, roundedcorners)
    End Function
#End Region

#Region "MSNLike"
    Public Shared Function MSNLike(ByVal rect As RectangleF, Optional ByVal tabwidth As Integer = 100, Optional ByVal tabheight As Integer = 20, Optional ByVal cornerradius As Integer = 5, Optional ByVal margin As Integer = 2, Optional ByVal roundedcorners As Corner = Corner.All) As Drawing2D.GraphicsPath
        Dim p As New Drawing2D.GraphicsPath
        Dim x As Single = rect.X, y As Single = rect.Y, w As Single = rect.Width, h As Single = rect.Height, m As Single = margin, r As Integer = cornerradius, tw As Integer = tabwidth, th As Integer = tabheight

        p.StartFigure()
        'top left arc
        If CBool(roundedcorners And Corner.TopLeft) Then
            p.AddArc(Helpers.CheckedRectangleF(x + m, y + m + th, 2 * r, 2 * r), 180, 90)
        Else
            p.AddLine(New PointF(x + m, y + m + r + th), New PointF(x + m, y + m + th))
            p.AddLine(New PointF(x + m, y + m + th), New PointF(x + m + r, y + m + th))
        End If

        'top line standard
        p.AddLine(New PointF(x + m + r, y + m + th), New PointF(x + w - m - tw - th, y + m + th))

        'bezier zwischen linie std und linie tab
        p.AddBezier( _
            New PointF(x + w - m - tw - th, y + m + th), _
            New PointF(x + w - m - tw, y + m + th), _
            New PointF(x + w - m - tw, y + m), _
            New PointF(x + w - m - tw + th, y + m))

        'linie tab bis ende
        p.AddLine(New PointF(x + w - m - tw + th, y + m), New PointF(x + w - m - r, y + m))

        'top right arc
        If CBool(roundedcorners And Corner.TopRight) Then
            p.AddArc(Helpers.CheckedRectangleF(x + w - m - 2 * r, y + m, 2 * r, 2 * r), 270, 90)
        Else
            p.AddLine(New PointF(x + w - m - r, y + m), New PointF(x + w - m, y + m))
            p.AddLine(New PointF(x + w - m, y + m), New PointF(x + w - m, y + m + r))
        End If

        'right line
        p.AddLine(New PointF(x + w - m, y + m + r), New PointF(x + w - m, y + h - m - r))

        'bottom right arc
        If CBool(roundedcorners And Corner.BottomRight) Then
            p.AddArc(Helpers.CheckedRectangleF(x + w - m - 2 * r, y + h - m - 2 * r, 2 * r, 2 * r), 0, 90)
        Else
            p.AddLine(New PointF(x + w - m, y + h - m - r), New PointF(x + w - m, y + h - m))
            p.AddLine(New PointF(x + w - m, y + h - m), New PointF(x + w - m - r, y + h - m))
        End If

        'bottom line
        p.AddLine(New PointF(x + w - m - r, y + h - m), New PointF(x + m + r, y + h - m))

        'bottom left arc
        If CBool(roundedcorners And Corner.BottomLeft) Then
            p.AddArc(Helpers.CheckedRectangleF(x + m, y + h - m - 2 * r, 2 * r, 2 * r), 90, 90)
        Else
            p.AddLine(New PointF(x + m + r, y + h - m), New PointF(x + m, y + h - m))
            p.AddLine(New PointF(x + m, y + h - m), New PointF(x + m, y + h - m - r))
        End If

        'left line
        p.AddLine(New PointF(x + m, y + h - m - r), New PointF(x + m, y + m + r))

        'close figure...
        p.CloseFigure()

        Return p
    End Function
#End Region

End Class

